import pygame, sys
from pygame.locals import *
import math
from datetime import datetime

#调速度
FPS = 20 # frames per second setting

WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED   = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE  = (0, 0, 255)
PINK  = (255, 0, 255)
GRAY  = pygame.Color('Gray')

#窗口基础大小
WIN_WIDTH = 400
WIN_HEIGHT = 300

#窗口缩放倍数
SCALE = 2

# 网格的左上角坐标
orgx = 100
orgy = 100

offx = 300
offy = 200

# 坐标原点
center_x = WIN_WIDTH * SCALE / 2
center_y = WIN_HEIGHT * SCALE / 2

''' 公式: y = A * sin(w*x + f) + b '''

''' 周期 '''
w = 1.0
T = 360 / w
A = WIN_HEIGHT / 2

''' 计算周期函数里每个x对应的sin值 '''
def MakeSinArr(w, T):
    sinArr = {}
    for degree in range(0, int(T)+1):
        ''' 角度转换为弧度值 '''
        rad = math.radians(degree)
        ''' 计算 sin(rad) 的值'''
        y = math.sin(rad * w)
        ''' 添加到字典里 '''
        sinArr[degree] = y
    return sinArr

def drawBg(sinArr):
    ''' 填充背景 白色 '''
    DISPLAYSURF.fill(pygame.Color("WHITE"))
    
    lineWeight = 2 * SCALE

    #画表盘
    pygame.draw.circle(DISPLAYSURF, pygame.Color('Cyan'), (center_x, center_y), A+10*SCALE, lineWeight)
    pygame.draw.circle(DISPLAYSURF, pygame.Color('Aqua'), (center_x, center_y), A+13*SCALE, lineWeight)
    pygame.draw.circle(DISPLAYSURF, pygame.Color('Cyan1'), (center_x, center_y), A+16*SCALE, lineWeight)
    
    ''' 画时钟数字 '''
    for x in range(30, 361, 30):
        posy = center_y - A * sinArr[int((x+90)%360)]
        posx = center_x + A * sinArr[int(x%360)]

        yUnitSurf = BASICFONT.render('%2d'%(x/30), True, BLACK)
        yUnitRect = yUnitSurf.get_rect()
        yUnitRect.center = (posx, posy)
        DISPLAYSURF.blit(yUnitSurf, yUnitRect)


'''  画时间信息 '''
def drawInfo(tm):
    infoSurf = BASICFONT.render(tm.strftime("%A, %d. %B %Y %I:%M %p"), True, BLACK)
    infoRect = infoSurf.get_rect()
    infoRect.center = (center_x, 20)

    DISPLAYSURF.blit(infoSurf, infoRect)

#画时针 分针 秒针
def DrawClockPin(sinArr, tm):

    lineWeight = 4 * SCALE

    houry = center_y - (A-80) * sinArr[int(((tm.hour % 12)*30+90)%T)]
    hourx = center_x + (A-80) * sinArr[int(((tm.hour % 12)*30)%T)]

    minutey = center_y - (A-50) * sinArr[int((tm.minute*6+90)%T)]
    minutex = center_x + (A-50) * sinArr[int((tm.minute*6)%T)]

    secondy = center_y - (A-10) * sinArr[int((tm.second*6+90)%T)]
    secondx = center_x + (A-10) * sinArr[int((tm.second*6)%T)]

    pygame.draw.line(DISPLAYSURF, GREEN, (center_x, center_y), (hourx, houry), lineWeight)
    pygame.draw.line(DISPLAYSURF, BLUE, (center_x, center_y), (minutex, minutey), lineWeight)
    pygame.draw.line(DISPLAYSURF, RED, (center_x, center_y), (secondx, secondy), lineWeight)

'''  初始化配置 '''
def initEvn():
    global center_x, center_y
    center_y = orgy + offy
    center_x = orgx + offx

def terminate():
    pygame.quit()
    sys.exit()

def main():
    global FPS, FPSCLOCK, DISPLAYSURF, BASICFONT, A, T, w
    pygame.init()
    
    fpsClock = pygame.time.Clock()

    # set up the window
    DISPLAYSURF = pygame.display.set_mode((WIN_WIDTH * SCALE, WIN_HEIGHT * SCALE), 0, 32)
    pygame.display.set_caption('时钟')

    BASICFONT = pygame.font.Font('freesansbold.ttf', 10 * SCALE)
    
    ''' 读取周期函数x与y的 映射 '''
    sinArr = MakeSinArr(w, T)
    
    ''' 画背景 '''
    drawBg(sinArr)

    Pause = False

    ''' 主循环 '''
    while True: # the main game loop
        #获取当前时间
        tm = datetime.now()
        
        if not Pause:
            # 画背景
            drawBg(sinArr)

            # 画函数信息
            drawInfo(tm)
        
            # 画秒针
            DrawClockPin(sinArr, tm)
        
        for event in pygame.event.get():
            # 键盘事件
            if (event.type == KEYDOWN):
                # 方向键 上 下 或者 w s 按下： 调整振幅 A
                if event.key == K_UP or event.key == K_w:
                    if A < WIN_HEIGHT:
                        A += 10
                elif event.key == K_DOWN or event.key == K_s:
                    if A > 50:
                        A -= 10
                    # 空格键按下暂停
                elif event.key == K_SPACE:
                    Pause = not Pause
                elif event.key == K_ESCAPE:
                    terminate()
            elif event.type == QUIT:
                terminate()

        pygame.display.update()
        fpsClock.tick(FPS)

if __name__ == '__main__':
    main()